feat(LipschitzSmooth): algebraic preservation lemmas#33
Draft
FordUniver wants to merge 5 commits into
Draft
Conversation
Change `LipschitzSmoothWith K f` from the one-sided descent inequality
f y ≤ f x + lineDeriv ℝ f x (y - x) + (K / 2) (dist x y)²
to the two-sided absolute-value form
|f y - f x - lineDeriv ℝ f x (y - x)| ≤ (K / 2) (dist x y)²
matching the textbook definition of L-smoothness (Lipschitz gradient,
class C^{1,1}) — orientation-agnostic, closed under f ↦ -f, and used in
Nesterov (Lemma 1.2.3), Beck (Ch. 5), Bauschke-Combettes (Lemma 2.64),
etc. The one-sided form admitted pathological cases like `-|x|` being
0-smooth, which the two-sided form excludes.
API changes:
- New primary extractor `lineDeriv_abs_le` (matching the def body).
- New lower-bound `lineDeriv_descent_ge` and two-sided variance
`lineDeriv_apply_sub_abs_le` extractors.
- New theoretical results unlocked: `LipschitzSmoothWith.hasLineDerivAt`
(line-differentiability everywhere — provable from the predicate's
bound `|f(x + tv) - f x - t·L| ≤ K/2 t²‖v‖² = o(t)`) and
`LipschitzSmoothWith.continuous`. Both currently `sorry`; full proofs
follow in subsequent commits.
- Existing extractors `lineDeriv_descent_le`, `lineDeriv_apply_sub_le`,
`lineDeriv_sub_apply_le` retained (one-sided, derived from the abs).
- Parallel additions in `FDeriv.lean`, `Deriv.lean`, `Gradient.lean`.
- `CocoerciveWith` and `CocoerciveWith.lipschitzWith_gradient` unchanged.
Fill in `LipschitzSmoothWith.hasLineDerivAt`: a `K`-smooth function is line-differentiable everywhere, and the `lineDeriv` value at every direction is the actual line derivative. The predicate bound |f(x + t·v) - f x - t · lineDeriv f x v| ≤ K/2 · t² · ‖v‖² (obtained by applying the abs-bound at `(x, x + t • v)` and factoring `t` via `lineDeriv_smul`) is `o(t)`, which is the `IsLittleO` form of `HasDerivAt` at `0` for the 1D restriction. The `continuous` field remains `sorry` pending a separate argument.
Basic.lean (K = 0 cases, no extra hypotheses): - `lipschitzSmoothWith_const`: constants are 0-smooth - `lipschitzSmoothWith_affine`: affine functions `y ↦ ℓ y + c` are 0-smooth Algebra.lean (new, imports `ContinuousAffineMap`): - `LipschitzSmoothWith.add`: closed under `+` with `K₁ + K₂` - `LipschitzSmoothWith.const_smul`: closed under nonneg `c •` with `c · K` - `LipschitzSmoothWith.comp_continuousAffineMap`: composition with continuous affine map `A` gives `‖A.contLinear‖² · K`-smooth (currently `sorry`) The `add` and `const_smul` lemmas require `Differentiable ℝ f` hypotheses because mathlib's `lineDeriv` doesn't have an unconditional additivity/scaling lemma (junk values when a summand is non-differentiable); the proofs route through the `fderiv`-form characterisation to sidestep this.
…ffineMap companion - `lipschitzSmoothWith_const` now derived as a one-liner from `lipschitzSmoothWith_affine` with `ℓ = 0` (was duplicated proof). - Add `lipschitzSmoothWith_continuousAffineMap` in `Algebra.lean` as the bundled `ContinuousAffineMap` companion to the linear+const form in `Basic.lean`. Mathematically cleanest statement, but stays in `Algebra.lean` since it pulls in `ContinuousAffineMap`.
…predicate The two-sided abs form of `LipschitzSmoothWith` (predicated on the weakest form `lineDeriv`) implies line-differentiability everywhere via `LipschitzSmoothWith.hasLineDerivAt`, so the algebraic preservation lemmas no longer require any `Differentiable ℝ f` hypothesis: - `add` works in pure `lineDeriv` form by computing `HasLineDerivAt (f₁ + f₂)` from the two pointwise `hasLineDerivAt` witnesses (via `HasDerivAt.add`), then chaining the triangle inequality with the two abs bounds. - `const_smul` analogously via `HasDerivAt.const_smul` and `abs_mul` plus `abs_of_nonneg` (since `c : NNReal ≥ 0`). - `neg` becomes trivial under the abs predicate (it was not provable under the old one-sided descent form), with the *same* constant `K`. Also fix the `lipschitzSmoothWith_affine` proof in `Basic.lean` (the post-`map_sub` goal is now `|0| ≤ 0` rather than the old descent `linarith`-trivial goal, so the closing tactic switches to `simp`). The module docstring is updated to drop the (now-false) "not closed under negation" caveat — that was a consequence of the one-sided form and disappears in the two-sided form. The deferred-follow-up sorry on `comp_continuousAffineMap` is unchanged.
c47d7c2 to
3ed2362
Compare
9437e2a to
6b44bc9
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Algebraic preservation lemmas for
LipschitzSmoothWith: closure under+, nonnegc •, and composition with continuous affine maps, plus the K=0 base cases for constants and affine functions.Sketch / WIP — proof status:
lipschitzSmoothWith_const✅ proved (Basic.lean, 5 lines)lipschitzSmoothWith_affine✅ proved (Basic.lean, 5 lines)lipschitzSmoothWith_continuousAffineMap✅ proved (Algebra.lean, 3 lines, derived from_affine)LipschitzSmoothWith.add✅ proved (Algebra.lean, 9 lines, requiresDifferentiable ℝ f₁/f₂— necessary)LipschitzSmoothWith.const_smul✅ proved (Algebra.lean, 9 lines, requiresDifferentiable ℝ f— necessary)LipschitzSmoothWith.comp_continuousAffineMap⚠sorryplaceholderOn the
DifferentiablehypothesisA critical reading of Cannarsa-Sinestrari 2004 (Chapter 3) initially suggested these hypotheses might be removable via an implicit line-differentiability extractor
LipschitzSmoothWith.hasLineDerivAt. They cannot. Concrete counterexamples:f(x) = -|x|on ℝ satisfiesLipschitzSmoothWith 0(the descent inequality holds becauselineDerivhappens to be junk =0at the kink andf ≤ 0globally) butHasLineDerivAt ℝ f 0 0 1fails — the one-sided limits-sign(t)disagree.f₁(x, y) = -|x|andf₂(x, y) = -2yare eachLipschitzSmoothWith 0, but the sumf₁ + f₂is not (predicate fails at(0,0)against(0.01, -10):19.99 ≤ 0is false).Root cause: our predicate is strictly stronger than the semiconcavity class Cannarsa-Sinestrari work with — it requires the descent inequality with mathlib's specific junk-valued
lineDeriv, whereas semiconcavity only requires some super-gradient.So the
Differentiablehypothesis onadd/const_smulis necessary, not a stopgap.File split
K=0 cases (
lipschitzSmoothWith_const,lipschitzSmoothWith_affine) live inBasic.leansince they need no new imports. The rest live in a newAlgebra.leanwhich pulls inMathlib.Analysis.Normed.Affine.ContinuousAffineMap— keeping that import out ofBasic.leanso it doesn't cascade through the rest of the LipschitzSmooth API.LipschitzSmoothWithandCocoerciveWithleanprover-community/mathlib4#39574 (feat/lipschitzSmooth-basic)Diff for the changes just in this PR over its predecessor: link